package nachos.threads;

import nachos.machine.*;

public class KThreadTest {

    private static class TestThread implements Runnable 
	{
		TestThread(int id, int upTo)
		{
			this.id = id;
			this.upTo = upTo;
		}
	
		public void run() 
		{
			for (int i=0; i<upTo; ++i) 
			{
				System.out.println("    Thread#" + id + " looped " + i + " times");
				KThread.yield();
			}
			System.out.println("    Thread#" + id + " done");
		}

		public int id;
		private int upTo;
    }

    private static class Joiner implements Runnable 
	{
		Joiner(int id, KThread thread1,int thread1_id) 
		{
			this.id = id;
			this.thread1 = thread1;
			this.thread1_id = thread1_id;
		}
	
		public void run() 
		{
			if (thread1 != null) 
			{
				System.out.println("    Join Thread#"+ id +" joining with Thread#"+thread1_id);
				thread1.join();
				System.out.println("    Join Thread#"+id+" joined with Thread#"+thread1_id);
			}
			System.out.println("    Join Thread#"+id+" done.");
		}

		public int id;
		private int thread1_id;
		private KThread thread1;
    }

    public static void runTest() 
	{
		System.out.println("  KThread.join() testing begins");
	
		KThread threads[] = new KThread[3];
		for (int i=0; i < 3; i++) 
		{
			threads[i] = new KThread(new TestThread((3*(i+1))-1,3*(i+1)));
			threads[i].fork();
        }

		KThread joinThread1 = new KThread(new Joiner(0,threads[0],2));
		joinThread1.fork();

        KThread joinThread2 = new KThread(new Joiner(1,threads[2],8));
        joinThread2.fork();

        for (int i=0; i < 3; i++) 
		{
			threads[i].join();
		}
	
		joinThread1.join();
		joinThread2.join();

		System.out.println("  KThread.join() testing ends");
    }

}
